﻿using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEngine.UI;
using System.Linq;

namespace HKTools
{
    /// <summary>
    /// 用于存储 UI 边框预览工具所有相关设置的结构体。
    /// </summary>
    public struct UIBorderPreviewSettings
    {
        public bool isToolEnabled; // 工具是否启用
        public bool isShowName;
        public bool isShowSize;
        public bool isShowAnchorPos;
        public float borderThickness; // 边框线宽
        public Dictionary<string, HK_UIBorderPreviewWindow.ComponentSetting> componentSettingsMap; // 组件设置的映射 (TypeName -> Setting)

        /// <summary>
        /// 尝试获取指定组件类型的启用设置。
        /// </summary>
        /// <param name="componentType">要检查的组件类型。</param>
        /// <param name="setting">如果找到并启用，则输出对应的设置。</param>
        /// <returns>如果组件类型被启用，则返回 true。</returns>
        public bool TryGetEnabledComponentSetting(System.Type componentType, out HK_UIBorderPreviewWindow.ComponentSetting setting)
        {
            setting = null;
            if (!isToolEnabled) return false;

            string typeNameToCheck = componentType.FullName;
            if (HK_UIBorderPreviewWindow.IsTextMeshProAvailable && componentType == HK_UIBorderPreviewWindow.TextMeshProUGUIType)
            {
                typeNameToCheck = "TMPro.TextMeshProUGUI"; // Use the key stored in the map
            }

            if (componentSettingsMap.TryGetValue(typeNameToCheck, out var foundSetting))
            {
                if (foundSetting.isEnabled)
                {
                    setting = foundSetting;
                    return true;
                }
            }
            return false;
        }
    }

    /// <summary>
    /// UI 边框预览工具的编辑器窗口，用于配置设置。
    /// </summary>
    public class HK_UIBorderPreviewWindow : EditorWindow
    {
        /// <summary>
        /// 存储单个组件类型的预览设置。
        /// </summary>
        [System.Serializable]
        public class ComponentSetting
        {
            /// <summary>
            /// 组件的类型名称 (通常是 FullName，TMPro 除外)。用作字典键。
            /// </summary>
            public string componentName;
            /// <summary>
            /// 是否为此类型组件启用边框预览。
            /// </summary>
            public bool isEnabled = true;
            /// <summary>
            /// 此类型组件的边框颜色。
            /// </summary>
            public Color color = Color.white;
            /// <summary>
            /// 用于 EditorPrefs 的启用状态键。
            /// </summary>
            public string EnabledPrefKey => $"UIBorderPreview_{componentName}_Enabled";
            /// <summary>
            /// 用于 EditorPrefs 的颜色键。
            /// </summary>
            public string ColorPrefKey => $"UIBorderPreview_{componentName}_Color";

            public ComponentSetting(string name, Color defaultColor)
            {
                componentName = name;
                color = defaultColor;
            }
        }

        static List<ComponentSetting> componentSettingsList = new List<ComponentSetting>();
        static Dictionary<string, ComponentSetting> componentSettingsMap = new Dictionary<string, ComponentSetting>(); // Map for faster lookup
        static bool isShowName;
        static bool isShowSize;
        static bool isShowAnchorPos;
        static bool isToolEnabled = true;
        static float borderThickness = 2.0f; // 添加线宽设置，默认值2.0f

        const string ShowDetailsPrefKey = "UIBorderPreview_ShowDetails";
        const string ShowNamePrefKey = "UIBorderPreview_ShowName";
        const string ShowSizePrefKey = "UIBorderPreview_ShowSize";
        const string ShowAnchorPosPrefKey = "UIBorderPreview_ShowAnchorPos";
        const string ToolEnabledPrefKey = "UIBorderPreview_ToolEnabled";
        const string BorderThicknessPrefKey = "UIBorderPreview_BorderThickness"; // 线宽的 Pref Key

        // TextMeshPro 相关类型名称
        const string TextMeshProUGUITypeName = "TMPro.TextMeshProUGUI";
        /// <summary>Gets TextMeshProUGUI 的 Type 对象，如果可用。</summary>
        public static System.Type TextMeshProUGUIType { get; private set; } = null;
        /// <summary>Gets a value indicating whether TextMeshPro 是否在项目中可用。</summary>
        public static bool IsTextMeshProAvailable { get; private set; } = false;

        /// <summary>
        /// 通过菜单项打开编辑器窗口。
        /// </summary>
        [MenuItem("HKTools/HK_UIBorderPreview(UI边框预览)", priority = HK_MenuPriority.HK_UIBorderPreview)]
        public static void ShowWindow()
        {
            GetWindow<HK_UIBorderPreviewWindow>("UI Border Preview");
        }

        /// <summary>
        /// 窗口启用时调用
        /// </summary>
        void OnEnable()
        {
            InitializeSettings();
            LoadSettings();
        }

        /// <summary>
        /// 窗口禁用时调用
        /// </summary>
        void OnDisable()
        {
            SaveSettings();
        }

        /// <summary>
        /// 初始化默认的组件设置列表和映射。
        /// </summary>
        static void InitializeSettings()
        {
            if (componentSettingsList.Count > 0) return;

            var tempList = new List<ComponentSetting>();
            tempList.Add(new ComponentSetting(typeof(Image).FullName, Color.cyan));
            tempList.Add(new ComponentSetting(typeof(RawImage).FullName, Color.magenta));
            tempList.Add(new ComponentSetting(typeof(Button).FullName, Color.green));
            tempList.Add(new ComponentSetting(typeof(Slider).FullName, Color.yellow));
            tempList.Add(new ComponentSetting(typeof(Toggle).FullName, Color.blue));
            tempList.Add(new ComponentSetting(typeof(Scrollbar).FullName, Color.red));
            tempList.Add(new ComponentSetting(typeof(ScrollRect).FullName, Color.gray));
            tempList.Add(new ComponentSetting(typeof(Text).FullName, Color.white));
            tempList.Add(new ComponentSetting(typeof(InputField).FullName, Color.black));
            // tempList.Add(new ComponentSetting(typeof(Canvas).FullName, Color.yellow)); // 添加 Canvas, 使用黄色

            TextMeshProUGUIType = System.Type.GetType($"{TextMeshProUGUITypeName}, Unity.TextMeshPro");
            IsTextMeshProAvailable = TextMeshProUGUIType != null;

            if (IsTextMeshProAvailable)
            {
                tempList.Add(new ComponentSetting(TextMeshProUGUITypeName, new Color(1f, 0.5f, 0f)));
            }

            componentSettingsList = tempList;
            UpdateSettingsMap(); // Populate the map
        }

        /// <summary>
        /// 根据当前的设置列表更新字典映射。
        /// </summary>
        static void UpdateSettingsMap()
        {
            componentSettingsMap = componentSettingsList.ToDictionary(s => s.componentName, s => s);
        }

        /// <summary>
        /// 绘制编辑器窗口的 GUI。
        /// </summary>
        void OnGUI()
        {
            InitializeSettings(); // Ensure settings are initialized if window is opened after assembly reload

            EditorGUI.BeginChangeCheck();

            isToolEnabled = EditorGUILayout.Toggle("启用预览", isToolEnabled);
            EditorGUILayout.Space();

            isShowName = EditorGUILayout.Toggle("显示名称", isShowName);
            EditorGUILayout.Space();

            isShowSize = EditorGUILayout.Toggle("显示尺寸", isShowSize);
            EditorGUILayout.Space();

            isShowAnchorPos = EditorGUILayout.Toggle("显示锚点", isShowAnchorPos);
            EditorGUILayout.Space();

            borderThickness = EditorGUILayout.FloatField("边框宽度", borderThickness);
            if (borderThickness < 0.5f) borderThickness = 0.5f; // 限制最小宽度
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("组件边框设置:", EditorStyles.boldLabel);


            foreach (var setting in componentSettingsList)
            {
                EditorGUILayout.BeginHorizontal();
                setting.isEnabled = EditorGUILayout.ToggleLeft(setting.componentName, setting.isEnabled, GUILayout.Width(250)); // Increased width for full names
                setting.color = EditorGUILayout.ColorField(setting.color);
                EditorGUILayout.EndHorizontal();
            }

            if (EditorGUI.EndChangeCheck())
            {
                UpdateSettingsMap();
                SaveSettings();
                SceneView.RepaintAll();
            }

            EditorGUILayout.Space();
            if (GUILayout.Button("重置为默认值"))
            {
                ResetSettings();
                LoadSettings(); // Reload after resetting
                UpdateSettingsMap();
                SceneView.RepaintAll();
            }
        }

        /// <summary>
        /// 从 EditorPrefs 加载所有设置。
        /// </summary>
        static void LoadSettings()
        {
            InitializeSettings();
            isToolEnabled = EditorPrefs.GetBool(ToolEnabledPrefKey, true);
            isShowName = EditorPrefs.GetBool(ShowNamePrefKey, true);
            isShowSize = EditorPrefs.GetBool(ShowSizePrefKey, true);
            isShowAnchorPos = EditorPrefs.GetBool(ShowAnchorPosPrefKey, true);
            borderThickness = EditorPrefs.GetFloat(BorderThicknessPrefKey, 2.0f); // 加载线宽

            foreach (var setting in componentSettingsList)
            {
                setting.isEnabled = EditorPrefs.GetBool(setting.EnabledPrefKey, true);
                string colorString = EditorPrefs.GetString(setting.ColorPrefKey, ColorUtility.ToHtmlStringRGBA(setting.color));
                ColorUtility.TryParseHtmlString("#" + colorString, out setting.color);
            }
            UpdateSettingsMap(); // Update map after loading list
        }

        /// <summary>
        /// 将当前所有设置保存到 EditorPrefs。
        /// </summary>
        static void SaveSettings()
        {
            EditorPrefs.SetBool(ToolEnabledPrefKey, isToolEnabled);
            EditorPrefs.SetBool(ShowNamePrefKey, isShowName);
            EditorPrefs.SetBool(ShowSizePrefKey, isShowSize);
            EditorPrefs.SetBool(ShowAnchorPosPrefKey, isShowAnchorPos);
            EditorPrefs.SetFloat(BorderThicknessPrefKey, borderThickness); // 保存线宽

            foreach (var setting in componentSettingsList)
            {
                EditorPrefs.SetBool(setting.EnabledPrefKey, setting.isEnabled);
                EditorPrefs.SetString(setting.ColorPrefKey, ColorUtility.ToHtmlStringRGBA(setting.color));
            }
        }

        /// <summary>
        /// 重置所有设置，删除相关的 EditorPrefs 键，并重新初始化为默认值。
        /// </summary>
        static void ResetSettings()
        {
            EditorPrefs.DeleteKey(ToolEnabledPrefKey);
            EditorPrefs.DeleteKey(ShowDetailsPrefKey);
            EditorPrefs.DeleteKey(BorderThicknessPrefKey); // 重置时删除线宽 Key

            // Need to iterate through a temporary copy of keys if list is cleared immediately
            var keysToDelete = componentSettingsList.Select(s => s.componentName).ToList();
            foreach (var key in keysToDelete)
            {
                EditorPrefs.DeleteKey($"UIBorderPreview_{key}_Enabled");
                EditorPrefs.DeleteKey($"UIBorderPreview_{key}_Color");
            }

            componentSettingsList.Clear();
            componentSettingsMap.Clear();
            InitializeSettings(); // Re-initialize list and map
        }

        /// <summary>
        /// 获取包含所有当前设置的结构体。
        /// 这是供绘图器使用的主要接口。
        /// </summary>
        /// <returns>包含当前设置的 UIBorderPreviewSettings 结构体。</returns>
        public static UIBorderPreviewSettings GetCurrentSettings()
        {
            LoadSettings();

            return new UIBorderPreviewSettings
            {
                isToolEnabled = isToolEnabled,
                isShowName = isShowName,
                isShowSize = isShowSize,
                isShowAnchorPos = isShowAnchorPos,
                borderThickness = borderThickness,
                componentSettingsMap = new Dictionary<string, ComponentSetting>(componentSettingsMap)
            };
        }
    }
}